﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using Common.Dao;
using Common.Model;
using log4net;
using Newtonsoft.Json;
using Spider.Mode;

namespace Spider.Spider
{
    public class P5WSpider
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(P5WSpider));
        
        public static void Test()
        {
            var p5WSpider = new Spider.P5WSpider();
            var qAnswers = p5WSpider.GetQuestion(DateTime.Parse("2018-01-17"), true);
            
            qAnswers.ForEach(m =>
            {
                Log.Info("Pid\t = "+m.Pid);
                Log.Info("Code\t = "+m.Code);
                Log.Info("QuestionTime\t = "+m.QuestionTime);
                Log.Info("Question\t = "+m.Question);
                Log.Info("AnswerTime\t = "+m.AnswerTime);
                Log.Info("Answer\t = "+m.Answer);
                Log.Info("===================");
            });
            QuestionAnswerDao.BatchSaveQuestion(qAnswers);
        }

        private readonly int _sleepTime = 1000;

        public P5WSpider(int sleepTime)
        {
            _sleepTime = sleepTime;
        }

        public P5WSpider()
        {
            _sleepTime = 0;
        }
        
        /// <summary>
        /// 获取全景互动的问答数据，开始时间至现在
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="withAnswer">true 只获取有回答的，fals只获取未回答的</param>
        /// <param name="keyword">搜索关键字</param>
        /// <returns></returns>
        public List<QAnswer> GetQuestion(DateTime startTime, bool withAnswer, string keyword = null)
        {
            return GetQuestion(startTime, withAnswer, DateTime.Now, keyword);
        }
        
        /// <summary>
        /// 获取全景互动的问答数据，开始时间至结束时间
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="withAnswer">true 只获取有回答的，fals只获取未回答的</param>
        /// <param name="keyword">搜索关键字</param>
        /// <param name="endTime">结束时间</param>
        /// <returns></returns>
        public List<QAnswer> GetQuestion(DateTime startTime, bool withAnswer, DateTime endTime ,string keyword = null)
        {


            List<QAnswer> qAnswers = new List<QAnswer>();

            for (int i = 0; i < Int32.MaxValue; i++)
            {
                string json = null;
                try
                {
                    json = GetJson(i, keyword, withAnswer);
                }
                catch (Exception e)
                {
                    Log.Error("start time = " + startTime + ",endTime = " + endTime + ",withAnswer  = " + withAnswer +
                              ",page = " + i + "\r\n" + e);
                    break;
                }

                Thread.Sleep(_sleepTime);
                QAMode qaMode = JsonConvert.DeserializeObject<QAMode>(json);

                List<Row> rows = qaMode.rows;

                if (withAnswer)
                {
                    if(rows.Any(m => m.replyList[0].replyerTimeStr < startTime))
                    {
                        qAnswers.AddRange(rows
                            .Where(m => m.replyList[0].replyerTimeStr > startTime &&
                                        m.replyList[0].replyerTimeStr < endTime).Select(m => new QAnswer()
                            {
                                Answer = m.replyList[0].replyContent,
                                AnswerTime = m.replyList[0].replyerTimeStr,
                                Code = m.companyBaseInfo.companyCode,
                                Pid = m.pid,
                                Question = m.content,
                                QuestionTime = m.questionerTimeStr
                            }).ToList());
                        break;
                    }
                    else
                    {
                        if (rows.Count < 0)
                        {
                            break;
                        }
                    }
                    qAnswers.AddRange(rows.Where(m => m.replyList[0].replyerTimeStr < endTime).Select(m => new QAnswer()
                    {
                        Answer = m.replyList[0].replyContent,
                        AnswerTime = m.replyList[0].replyerTimeStr,
                        Code = m.companyBaseInfo.companyCode,
                        Pid = m.pid,
                        Question = m.content,
                        QuestionTime = m.questionerTimeStr
                    }).ToList());
                }
                else
                {
                    if (rows.Any(m => m.questionerTimeStr < startTime))
                    {
                        qAnswers.AddRange(rows
                            .Where(m => m.questionerTimeStr > startTime && m.questionerTimeStr < endTime).Select(m =>
                                new QAnswer()
                                {
                                    Code = m.companyBaseInfo.companyCode,
                                    Pid = m.pid,
                                    Question = m.content,
                                    QuestionTime = m.questionerTimeStr
                                }).ToList());
                        break;
                    }else
                    {
                        if (rows.Count < 0)
                        {
                            break;
                        }
                    }
                    qAnswers.AddRange(rows.Where(m => m.questionerTimeStr < endTime).Select(m => new QAnswer()
                    {
                        Code = m.companyBaseInfo.companyCode,
                        Pid = m.pid,
                        Question = m.content,
                        QuestionTime = m.questionerTimeStr
                    }).ToList());
                }
            }
            return qAnswers;
        }

        private static string GetJsonWithKeyWord(string url,int page,string keyWord,bool withAnswer)
        {
            var httpWebRequest = GetRequest(page, keyWord, withAnswer);

            HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();

            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }
             
        private static HttpWebRequest GetRequest(int page,string keyWords,bool withAnswer)
        {
            string url = "http://rs.p5w.net/interaction/getNewSearch" + (withAnswer ? "R" : "Q") + ".shtml";

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);

            request.Method = WebRequestMethods.Http.Post;

            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
            request.Referer = "http://rs.p5w.net/question/";
            
//            var cookieContainer = new CookieContainer(3);
//            request.CookieContainer = cookieContainer;

//            var cookie = new Cookie("__ckMd5", "e20dceb56bd7b422");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("vjuids", "1c696d575.160e9506e78.0.7894daaf790eb");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("vjlast", "1515742851.1515742851.30");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("Hm_lvt_ed9dac8a2b525df95dc69c97bbcda470", HttpUtility.UrlEncode("1515571280,1515630796,1516005283"));
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("SHRIOSESSIONID", "86cfb430-7712-4a90-83ec-e09b1c657175");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("JSESSIONID", "2D2FD9973C7BEE5CB23C060414BF4620");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);
//
//            cookie = new Cookie("Hm_lpvt_ed9dac8a2b525df95dc69c97bbcda470", "1516166592");
//            request.CookieContainer.Add(new Uri("http://rs.p5w.net/question/"), cookie);

            Stream stream = request.GetRequestStream();
            Encoding encoding = Encoding.UTF8;

            string param = "isPagination=1&page=" + page + "&rows=" + (withAnswer ? "10" : "20");
            
            if (!withAnswer)
            {
                param = "query=1&" + param;
            }

            if (null != keyWords)
            {
                param = "keyWords=" + keyWords + param;
            }
            
            byte[] data = encoding.GetBytes(param);
            
            stream.Write(data, 0, data.Length);
            stream.Close();
            return request;
        }

        /// <summary>
        /// 获取json
        /// </summary>
        private static string GetJson(int page,string keyword,bool withAnswer)
        {
            var httpWebRequest = GetRequest(page, keyword, withAnswer);

            HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();

            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }
    }
}